package joc.internal.transformer;

import javassist.ClassPool;
import javassist.CtBehavior;
import javassist.CtClass;
import javassist.CtMethod;
import joc.Condition;
import joc.PreCondition;

public class CustomPreConditionBehaviorTransformer extends DeclaredBehaviorTransformer {

	public CustomPreConditionBehaviorTransformer(ClassPool pool) {
		super(pool);
	}

	@Override
	public void transform(CtClass clazz, CtBehavior behavior) throws Exception {
		logger.info("behavior " + behavior.getLongName());
		if (behavior.hasAnnotation(PreCondition.class)) {
			PreCondition annotation = (PreCondition) behavior.getAnnotation(PreCondition.class);
			for (Class<?> pcClass : annotation.value()) {
				applyPreCondition(behavior, pcClass.getName());
			}
		}
	}

	private void applyPreCondition(CtBehavior behavior, String pcClassName) throws Exception {
		logger.info("behavior " + behavior.getLongName() + " has post-condition " + pcClassName);
		CtClass annotationClass = pool.get(pcClassName);
		String insertBefore = initializeConditionString(pcClassName);
		for (CtMethod pcMethod : annotationClass.getDeclaredMethods()) {
			if (pcMethod.hasAnnotation(Condition.class)) {
				insertBefore += callConditionString(pcMethod, true, behavior, false);
			}
		}
		logger.info("insertBefore: " + insertBefore);
		insertBefore(behavior, insertBefore);
	}

}
